package com.example.onlinemusicserver.controller;

import com.example.onlinemusicserver.model.Music;
import com.example.onlinemusicserver.model.User;
import com.example.onlinemusicserver.service.CollectService;
import com.example.onlinemusicserver.service.MusicService;
import com.example.onlinemusicserver.tools.Constant;
import com.example.onlinemusicserver.tools.ResponseBodyMessage;
import org.apache.ibatis.binding.BindingException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.UUID;

@RestController
@RequestMapping("/music")
public class MusicController {
    @Autowired
    private MusicService musicService;

    @Autowired
    private CollectService collectService;

    @Value("${upload.path}")
    public String SAVE_PATH;

    @Value("${uploadImg}")
    public String IMG_PATH;

    @Value("D:/worker/Practice/imgs")
    public String IMG_PATH2;
    /**
     * 上传音乐
     * @param singer
     * @param file
     * @param request
     * @return
     */
    @RequestMapping("/upload")
    public ResponseBodyMessage<Boolean> insertMusic(@RequestPart("singer") String singer,
                                                    @RequestPart("filename") MultipartFile file,
                                                    @RequestPart("imgname") MultipartFile img,
                                                    HttpServletRequest request,
                                                    HttpServletResponse response) {
        // 检测登录
        HttpSession session = request.getSession(false);
        if (session == null || session.getAttribute(Constant.USER_SESSION_KEY) == null) {
            System.out.println("当前未登录!");
            return new ResponseBodyMessage<>(-1,"请登录后上传",false);
        }

        // 文件的类型
        String fileNameAndType = file.getOriginalFilename();
        String imgType = img.getOriginalFilename();
        String ext = img.getOriginalFilename().substring(img.getOriginalFilename().lastIndexOf("."));
        String imgNewName = UUID.randomUUID().toString().replaceAll("-","")+ext;
        // 防止出现重复的相同歌曲和相同歌手.可以出现相同歌曲不同歌手
        String title = fileNameAndType.substring(0,fileNameAndType.lastIndexOf('.'));
        // 可能出现多首名称相同的歌曲, 所以用 List
        List<Music> list = musicService.selectByTitle(title);
        if(list != null){
            for(Music music : list) {
                if(music.getAuthor().equals(singer)){
                    return new ResponseBodyMessage<>(-1,"当前歌手的歌曲已经存在!",false);
                }
            }
        }

        // 创建文件
        String path = SAVE_PATH +singer+"-"+fileNameAndType;
        String path2 = IMG_PATH + imgNewName;
        File dest = new File(path);
        if(!dest.exists()) {
            dest.mkdirs();
        }
        File dest2 = new File(path2);
        if(!dest2.exists()) {
            dest2.mkdirs();
        }

        try {
            file.transferTo(dest);
            //return new ResponseBodyMessage<>(1,"上传成功!",true);
        } catch (IOException e) {
            e.printStackTrace();
            return new ResponseBodyMessage<>(-1,"服务器上传音乐文件失败!",false);
        }

        try {
            img.transferTo(dest2);
        } catch (IOException e) {
            e.printStackTrace();
            return new ResponseBodyMessage<>(-1,"服务器上传图片文件失败!",false);
        }

        // 这里对是不是 MP3 文件进行判断. 主要是判断是否存在 TAG 这个字符
        File file1 = new File(path);
        byte[] res = null;
        try {
            res = Files.readAllBytes(file1.toPath());
            if(res == null) {
                return new ResponseBodyMessage<>(-1,"当前文件不存在",false);
            }
            String str = new String(res);
            if(str.indexOf("ID3") != 0 && str.lastIndexOf("TAG") != str.length() - 128) {
                file1.delete();
                return new ResponseBodyMessage<>(-1,"当前不是mp3文件",false);
            }
        }catch (IOException e){
            e.printStackTrace();
            return new ResponseBodyMessage<>(-1,"服务器出现问题", false);
        }

        // 在数据库中上传数据
        User user = (User) session.getAttribute(Constant.USER_SESSION_KEY);
        // 这里传递的 path 没有带 `.MP3` 后期在前端进行设置
        String uploadPath = "/music/play?path="+singer+"-"+title;
        String imgPath = "/product/"+ imgNewName;
        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd");
        String uploadtime = sf.format(new Date());

        try {
            int ret = musicService.insert(title,singer,uploadtime,uploadPath,imgPath,user.getUserId());
            if(ret == 1) {
                // response.sendRedirect("/index.html");
                return new ResponseBodyMessage<>(1,"上传成功",true);
            }else {
                return new ResponseBodyMessage<>(-1,"数据库上传失败",false);
            }
        }catch (BindingException e) {
            dest.delete();
            dest2.delete();
            return new ResponseBodyMessage<>(-1,"数据库上传失败",false);
        }

    }

    /**
     * 播放音乐
     * @param path
     * @return
     */
    @RequestMapping("/play")
    public ResponseEntity<byte[]> playMusic(@RequestParam String path){
        File file = new File(SAVE_PATH + path);
        byte[] res = null;
        try {
            res = Files.readAllBytes(file.toPath());
            if (res == null) {
                return ResponseEntity.badRequest().build();
            }
            return ResponseEntity.ok(res);
        } catch (IOException e) {
            e.printStackTrace();
            return ResponseEntity.badRequest().build();
        }
    }

    /**
     * 删除音乐
     * @param musicId
     * @return
     */
    @RequestMapping("/delete")
    @Transactional
    public ResponseBodyMessage<Boolean> deleteMusic(@RequestParam String musicId) {
        // 1. 检测音乐是不是存在
        Music music = musicService.selectById(Integer.parseInt(musicId));
        // 2. 不存在直接返回, 存在就删除
        if (music == null) {
            System.out.println("该音乐不存在");
            return new ResponseBodyMessage<>(-1,"没有你要删除的音乐",false);
        }
        // 2.1 删除数据库中的记录
        int ret = musicService.deleteById(Integer.parseInt(musicId));
        if(ret == 1) {
            // 2.2 删除服务器上的数据
            int index = music.getPath().lastIndexOf("=");
            String PathName = music.getPath().substring(index+1);
            int index2 = music.getImgpath().lastIndexOf("/");
            String ImgName = music.getImgpath().substring(index2+1);
            File file = new File(SAVE_PATH + PathName+".mp3");
            File file1 = new File(IMG_PATH + ImgName);
            if(file.delete() && file1.delete()){
                collectService.deleteLoveMusicById(Integer.parseInt(musicId));
                return new ResponseBodyMessage<>(1,"删除成功!",true);
            }else{
                return new ResponseBodyMessage<>(-1,"服务器删除失败!",false);
            }
        }else {
            return new ResponseBodyMessage<>(-1,"数据库删除失败!",false);
        }
    }

    /**
     * 删除多选音乐
     * @param musicId
     * @return
     */
    @RequestMapping("/deleteMore")
    @Transactional
    public ResponseBodyMessage<Boolean> deleteMoreMusic(@RequestParam("musicId[]") List<Integer> musicId) {
        int sum = 0;
        for (int i = 0; i < musicId.size(); i++) {
            Music music = musicService.selectById(musicId.get(i));
            if (music == null) {
                return new ResponseBodyMessage<>(-1, "没有你要删除的音乐", false);
            }
            int ret = musicService.deleteById(musicId.get(i));
            if(ret == 1) {
                int index = music.getPath().lastIndexOf("=");
                int index2 = music.getImgpath().lastIndexOf("/");
                String ImgName = music.getImgpath().substring(index2+1);
                String PathName = music.getPath().substring(index + 1);
                File file1 = new File(IMG_PATH + ImgName);
                File file = new File(SAVE_PATH + PathName + ".mp3");
                if (file.delete() && file1.delete()) {
                    collectService.deleteLoveMusicById(musicId.get(i));
                    sum += ret;
                }else{
                    return new ResponseBodyMessage<>(-1,"服务器删除失败!",false);
                }
            }else{
                return new ResponseBodyMessage<>(-1,"数据库删除失败!",false);
            }
        }
        if(sum == musicId.size()) {
            return new ResponseBodyMessage<>(1,"音乐删除成功!",true);
        }else{
            return new ResponseBodyMessage<>(-1,"音乐删除失败!",false);
        }
    }

    /**
     * 支持模糊查询, 支持空查询
     * @param name
     * @return
     */
    @RequestMapping("/findMusic")
    public ResponseBodyMessage<HashMap<String,Object>> findMusic(@RequestParam(required = false) String name,
                                                      Integer pageIndex) {
        if(pageIndex <= 0) {
            return new ResponseBodyMessage<>(-1,"下标错误",null);
        }
        HashMap<String,Object> hash = new HashMap<>();
        List<Music> list = null;
        // 计算offset的后部分
        int pageRange = (pageIndex - 1) * Constant.PAGE_SIZE;
        // 计算总音乐数
        int totalMusic = musicService.totalMusic(name);
        if(totalMusic != 0 && pageIndex > Math.ceil(totalMusic*1.0/Constant.PAGE_SIZE)){
            return new ResponseBodyMessage<>(-1,"下标错误",null);
        }
        if(name != null && !"".equals(name)) {
            list = musicService.findMusicByName(name,pageRange,Constant.PAGE_SIZE);
        }else {
            list = musicService.findMusic(pageRange,Constant.PAGE_SIZE);
        }
        hash.put("list",list);
        hash.put("totalMusic",totalMusic);
        return new ResponseBodyMessage<>(1,"查询完毕!",hash);
    }
}
